package dbrouter

import (
	"context"
	"fmt"
	"io/ioutil"
	"sync"
)

//jsonConfig json配置
type jsonConfig struct {
	cfgFile  string
	parser   *Parser
	parserMu sync.RWMutex
}

//NewFileConfiger 新建配置实例
func NewFileConfiger(ctx context.Context, cfgFile string, dbChangeChan chan ConfigChange) (Configer, error) {
	fun := "NewFileConfiger -->"
	jsonConfig := &jsonConfig{
		cfgFile: cfgFile,
	}
	err := jsonConfig.init(ctx, dbChangeChan)
	if err != nil {
		fmt.Printf("%s init json configer err: %s\n", fun, err.Error())
		return nil, err
	}
	return jsonConfig, nil
}

func (e *jsonConfig) init(ctx context.Context, dbChangeChan chan ConfigChange) error {
	fun := "jsonConfig.init -->"
	data, err := ioutil.ReadFile(e.cfgFile)
	if err != nil {
		return err
	}
	parser, err := NewParser(data)
	if err != nil {
		fmt.Printf("%s init db parser err: %+v\n", fun, err.Error())
		return err
	}
	e.SetParser(ctx, parser)
	//todo 此处没有考虑动态加载问题
	return nil
}

func (e *jsonConfig) GetParser(ctx context.Context) *Parser {
	e.parserMu.RLock()
	defer e.parserMu.RUnlock()

	return e.parser
}

func (e *jsonConfig) SetParser(ctx context.Context, parser *Parser) {
	e.parserMu.Lock()
	defer e.parserMu.Unlock()

	e.parser = parser
}

//GetInstanceConfig 获取实例配置
func (e *jsonConfig) GetInstanceConfig(ctx context.Context, insName, group string) *Config {
	parser := e.GetParser(ctx)
	info := parser.getInstanceConfig(insName, group)
	return &Config{
		DBType:   info.DBType,
		DBAddr:   info.DBAddr,
		DBName:   info.DBName,
		UserName: info.UserName,
		PassWord: info.PassWord,
	}
}

//GetInstanceName 根据cluster以及table 获取实例名称
func (e *jsonConfig) GetInstanceName(ctx context.Context, cluster, table string) string {
	parser := e.GetParser(ctx)
	return parser.getInstanceName(cluster, table)
}

//GetAllGroups 获取所有的渠道（default or testing or ...）
func (e *jsonConfig) GetAllGroups(ctx context.Context) []string {
	var groups []string
	parser := e.GetParser(ctx)

	for group := range parser.dbIns {
		groups = append(groups, group)
	}
	return groups
}
